{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# GUI介绍\n",
    "- GraphicalUserInterface,\n",
    "- GUI for Python: Tkinter, wxPython, PyQt\n",
    "- TKinter:\n",
    "    - 绑定的是TK GUI工具集，用途Python包装的Tcl代码\n",
    "- PyGTK\n",
    "    - Tkinter的替代品\n",
    "- wxPython\n",
    "    - 跨平台的Python GUI\n",
    "- PyQt\n",
    "    - 跨平台的\n",
    "    - 商业授权可能由问题\n",
    "   \n",
    "- 推荐资料\n",
    "    - 辛星GUI， 辛星Python\n",
    "    - Python GUI Programming cookbook\n",
    "    - Tkinter reference a GUI for Python"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# 测试tkinter包是否好用\n",
    "import tkinter\n",
    "\n",
    "tkinter._test()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# hello world\n",
    "import tkinter\n",
    "\n",
    "base = tkinter.Tk()\n",
    "\n",
    "# 消息循环\n",
    "base.mainloop()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "###  Tkinter 常用组件\n",
    "- 按钮\n",
    "\n",
    "        Button\t\t\t\t按钮组件\n",
    "        RadioButton\t\t\t单选框组件\n",
    "        CheckButton\t\t\t选择按钮组件\n",
    "        Listbox\t\t\t\t列表框组件\n",
    "        \n",
    "- 文本输入组件\n",
    "    \n",
    "        Entry\t\t\t\t单行文本框组件\n",
    "        Text\t\t\t\t多行文本框组件\n",
    "        \n",
    "- 标签组件\n",
    "\n",
    "        Label\t\t\t\t标签组件，可以显示图片和文字\n",
    "        Message\t\t\t\t标签组件，可以根据内容将文字换行\n",
    "\t\n",
    "- 菜单\n",
    "        \n",
    "        Menu\t\t\t\t菜单组件\n",
    "        MenuButton\t\t\t菜单按钮组件，可以使用Menu代替\n",
    "        \n",
    "- 滚动条\n",
    "        \n",
    "        scale\t\t\t\t滑块组件\n",
    "        Scrollbar\t\t\t滚动条组件\n",
    "        \n",
    "-  其他组件\n",
    "\n",
    "        Canvas\t\t\t\t画布组件\n",
    "        Frame\t\t\t\t框架组件，将多个组件编组\n",
    "        Toplevel\t\t\t创建子窗口容器组件\n",
    "        \n",
    "### 组件的大致使用步骤\n",
    "1. 创建总面板\n",
    "2. 创建面板上的各种组件\n",
    "    1. 指定组件的父组件，即依附关系\n",
    "    2. 利用相应的属性对组件进行设置\n",
    "    3. 给组件安排布局\n",
    "    \n",
    "3. 同步骤2相似，创建好多个组件\n",
    "4. 最后，启动总面板的消息循环"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# Label的例子\n",
    "\n",
    "import tkinter\n",
    "\n",
    "base = tkinter.Tk()\n",
    "# 负责标题\n",
    "base.wm_title(\"Label Test\")\n",
    "\n",
    "lb = tkinter.Label(base, text=\"Python Label\")\n",
    "# 给相应组件指定布局\n",
    "lb.pack()\n",
    "\n",
    "\n",
    "base.mainloop()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# 设置Label的例子\n",
    "import tkinter\n",
    "\n",
    "\n",
    "base = tkinter.Tk()\n",
    "base.wm_title(\"Label Test\")\n",
    "# 支持属性很多background, font, underline等\n",
    "# 第一个参数，制定所属\n",
    "lb1= tkinter.Label(base, text=\"Python AI\")\n",
    "lb1.pack()\n",
    "\n",
    "lb2= tkinter.Label(base, text=\"绿色背景\", background=\"green\")\n",
    "lb2.pack()\n",
    "\n",
    "lb3= tkinter.Label(base, text=\"蓝色背景\", background=\"blue\")\n",
    "lb3.pack()\n",
    "\n",
    "base.mainloop()\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'\\nButton的属性：\\n\\nanchor \\t\\t\\t\\t设置按钮中文字的对其方式，相对于按钮的中心位置\\nbackground(bg) \\t\\t设置按钮的背景颜色\\nforeground(fg)\\t\\t设置按钮的前景色（文字的颜色）\\nborderwidth(bd)\\t\\t设置按钮边框宽度\\ncursor\\t\\t\\t\\t设置鼠标在按钮上的样式\\ncommand\\t\\t\\t\\t设定按钮点击时触发的函数\\nbitmap\\t\\t\\t\\t设置按钮上显示的位图\\nfont\\t\\t\\t\\t设置按钮上文本的字体\\nwidth\\t\\t\\t\\t设置按钮的宽度  (字符个数)\\nheight\\t\\t\\t\\t设置按钮的高度  (字符个数)\\nstate\\t\\t\\t\\t设置按钮的状态\\ntext\\t\\t\\t\\t设置按钮上的文字\\nimage\\t\\t\\t\\t设置按钮上的图片\\n\\n'"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Button的案例\n",
    "\n",
    "import tkinter\n",
    "\n",
    "def showLabel():\n",
    "    global baseFrame\n",
    "    # 在函数中定义了一个label\n",
    "    # label的父组件是baseFrame\n",
    "    lb = tkinter.Label(baseFrame, text=\"显示Label\")\n",
    "    lb.pack()\n",
    "\n",
    "\n",
    "baseFrame = tkinter.Tk()\n",
    "# 生成一个按钮\n",
    "# command参数指示，当按钮被按下的时候，执行哪个函数\n",
    "btn = tkinter.Button(baseFrame, text=\"Show Label\", command=showLabel)\n",
    "#btn = tkinter.Button(baseFrame, text=\"Show Label\")\n",
    "btn.pack()\n",
    "\n",
    "baseFrame.mainloop()\n",
    "\n",
    "'''\n",
    "Button的属性：\n",
    "\n",
    "anchor \t\t\t\t设置按钮中文字的对其方式，相对于按钮的中心位置\n",
    "background(bg) \t\t设置按钮的背景颜色\n",
    "foreground(fg)\t\t设置按钮的前景色（文字的颜色）\n",
    "borderwidth(bd)\t\t设置按钮边框宽度\n",
    "cursor\t\t\t\t设置鼠标在按钮上的样式\n",
    "command\t\t\t\t设定按钮点击时触发的函数\n",
    "bitmap\t\t\t\t设置按钮上显示的位图\n",
    "font\t\t\t\t设置按钮上文本的字体\n",
    "width\t\t\t\t设置按钮的宽度  (字符个数)\n",
    "height\t\t\t\t设置按钮的高度  (字符个数)\n",
    "state\t\t\t\t设置按钮的状态\n",
    "text\t\t\t\t设置按钮上的文字\n",
    "image\t\t\t\t设置按钮上的图片\n",
    "\n",
    "'''"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 组件布局\n",
    "- 控制组件的摆放方式\n",
    "- 三种布局：\n",
    "    - pack: 按照方位布局\n",
    "    - place: 按照坐标布局\n",
    "    - grid： 网格布局\n",
    "    \n",
    "- pack布局\n",
    "    - 最简单，代码量最少，挨个摆放，默认从上倒下，系统自动设置\n",
    "    - 通用使用方式为： 组件对象.pack(设置，，，，，，，）\n",
    "    - side: 停靠方位， 可选值为LEFT,TOP,RIGHT,BOTTON\n",
    "    - fill: 填充方式,X,Y,BOTH,NONE\n",
    "    - expande: YES/NO\n",
    "    - anchor: N,E,S,W,CENTER\n",
    "    - ipadx: x方向的内边距\n",
    "    - ipady: y\n",
    "    - padx: x方向外边界\n",
    "    - pady： y........\n",
    "    \n",
    "- grid布局\n",
    "    - 通用使用方式：组件对象.grid(设置,,,,,,,)\n",
    "    - 利用row，column编号，都是从0开始\n",
    "    - sticky： N,E,S,W表示上下左右，用来决定组件从哪个方向开始\n",
    "    - 支持ipadx，padx等参数，跟pack函数含义一样\n",
    "    - 支持rowspan，columnspan，表示跨行，跨列数量\n",
    "\n",
    "- place布局\n",
    "    - 明确方位的摆放\n",
    "    - 相对位置布局，随意改变窗口大小会导致混乱\n",
    "    - 使用place函数，分为绝对布局和相对布局，绝对布局使用x，y参数\n",
    "    - 相对布局使用relx，rely, relheight, relwidth"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# pack布局案例\n",
    "import tkinter\n",
    "\n",
    "baseFrame = tkinter.Tk()\n",
    "# 以下所有代码都是创建一个组件，然后布局\n",
    "\n",
    "btn1 = tkinter.Button(baseFrame, text='A')\n",
    "btn1.pack(side=tkinter.LEFT, expand=tkinter.YES, fill=tkinter.Y)\n",
    "\n",
    "btn2 = tkinter.Button(baseFrame, text='B')\n",
    "btn2.pack(side=tkinter.TOP, expand=tkinter.YES, fill=tkinter.BOTH)\n",
    "\n",
    "btn2 = tkinter.Button(baseFrame, text='C')\n",
    "btn2.pack(side=tkinter.RIGHT, expand=tkinter.YES, fill=tkinter.NONE, \n",
    "          anchor=tkinter.NE)\n",
    "\n",
    "btn2 = tkinter.Button(baseFrame, text='D')\n",
    "btn2.pack(side=tkinter.LEFT, expand=tkinter.NO, fill=tkinter.Y)\n",
    "\n",
    "btn2 = tkinter.Button(baseFrame, text='E')\n",
    "btn2.pack(side=tkinter.TOP, expand=tkinter.NO, fill=tkinter.BOTH)\n",
    "\n",
    "btn2 = tkinter.Button(baseFrame, text='F')\n",
    "btn2.pack(side=tkinter.BOTTOM, expand=tkinter.YES)\n",
    "\n",
    "btn2 = tkinter.Button(baseFrame, text='G')\n",
    "btn2.pack(anchor=tkinter.SE)\n",
    "\n",
    "\n",
    "\n",
    "baseFrame.mainloop()\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# grid布局案例\n",
    "import tkinter\n",
    "\n",
    "baseFrame = tkinter.Tk()\n",
    "\n",
    "#下面被注释掉的一行代码跟下面两行代码等效\n",
    "#lb1 = tkinter.Label(baseFrame, text=\"账号: \").grid(row=0, sticky= tkinter.W)\n",
    "lb1 = tkinter.Label(baseFrame, text=\"账号: \")\n",
    "lb1.grid(row=0, sticky= tkinter.W)\n",
    "\n",
    "en = tkinter.Entry(baseFrame)\n",
    "en.grid(row=0, column=1, sticky=tkinter.E)\n",
    "\n",
    "lb2 = tkinter.Label(baseFrame, text=\"密码: \").grid(row=1, sticky= tkinter.W)\n",
    "tkinter.Entry(baseFrame).grid(row=1, column=1, sticky=tkinter.E)\n",
    "\n",
    "btn = tkinter.Button(baseFrame, text=\"登录\").grid(row=2, column=1, sticky=tkinter.W)\n",
    "\n",
    "\n",
    "baseFrame.mainloop()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 消息机制\n",
    "- 消息的传递机制\n",
    "    - 自动发出事件/消息\n",
    "    - 消息有系统负责发送到队列\n",
    "    - 由相关组件进行绑定/设置\n",
    "    - 后端自动选择感兴趣的事件并做出相应反应\n",
    "- 消息格式：\n",
    "    - <[modifier-]---type-[-detail]>\n",
    "    - <Button-1>: Button表示一个按钮事件，1代表的是鼠标左键，2代表中键\n",
    "    - <KeyPress-A>: 键盘A键位\n",
    "    - <Control-Shift-KeyPress-A>: 同时按下Control，Shift，A三个键位\n",
    "    - <F1>:F1键盘\n",
    "    - [键位对应名称](https://infohost.nmt.edu/tcc/help/pubs/tkinter/web/key-names.html)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "哈哈，我被点击了\n"
     ]
    }
   ],
   "source": [
    "# 事件的简单例子\n",
    "import tkinter\n",
    "\n",
    "def baseLabel(event):\n",
    "        global  baseFrame\n",
    "        print(\"哈哈，我被点击了\")\n",
    "        lb = tkinter.Label(baseFrame, text=\"谢谢点击\")\n",
    "        lb.pack()\n",
    "\n",
    "# 画出程序的总框架\n",
    "baseFrame = tkinter.Tk()\n",
    "\n",
    "lb = tkinter.Label(baseFrame, text=\"模拟按钮\")\n",
    "# label绑定相应的消息和处理函数\n",
    "# 自动获取左键点击，并启动相应的处理函数baseLabel\n",
    "lb.bind(\"<Button-1>\", baseLabel)\n",
    "lb.pack()\n",
    "\n",
    "# 启动消息循环\n",
    "# 到此，表示程序开始运行\n",
    "baseFrame.mainloop()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Tkinter的绑定\n",
    "- bind_all: 全局范围的绑定，默认的是全局快捷键，比如F1是帮助文档\n",
    "- bind_class: 接受三个参数，第一个是类名，第二个是事件，第三个是操作\n",
    "    - w.bind_class(\"Entry\", \"<Control-V>, my_paste)\n",
    "- bind:单独对某一个实例绑定\n",
    "- unbind： 解绑，需要一个参数，即你要解绑哪个事件\n",
    "\n",
    "### Entry\n",
    "- 输入框，功能单一\n",
    "- entry[\"show\"] = \"*\", 设置遮挡字符\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# 输入框案例\n",
    "\n",
    "import tkinter\n",
    "\n",
    "# 模拟的是登录函数\n",
    "def reg():\n",
    "    # 从相应输入框中，得到用户的输入\n",
    "    name = e1.get()\n",
    "    pwd = e2.get()\n",
    "\n",
    "    t1 = len(name)\n",
    "    t2 = len(pwd)\n",
    "\n",
    "    if name == \"111\" and pwd == \"222\":\n",
    "        # 需要理解下面代码的含义\n",
    "        lb3[\"text\"] = \"登录成功\"\n",
    "    else:\n",
    "        lb3['text'] = \"用户名或密码错误\"\n",
    "        # 输入框删除掉用户输入的内容\n",
    "        # 注意delete的两个参数，表示从第几个删除到第几个\n",
    "        e1.delete(0,t1)\n",
    "        e2.delete(0,t2)\n",
    "        \n",
    "# 启动舞台\n",
    "baseFrame = tkinter.Tk()\n",
    "\n",
    "lb1 = tkinter.Label(baseFrame, text=\"用户名\")\n",
    "lb1.grid(row=0, column=0, stick=tkinter.W )\n",
    "\n",
    "e1 = tkinter.Entry(baseFrame)\n",
    "e1.grid(row=0, column=1, stick=tkinter.E)\n",
    "\n",
    "lb2 = tkinter.Label(baseFrame, text=\"密码: \")\n",
    "lb2.grid(row=1, column=0, stick=tkinter.W )\n",
    "\n",
    "e2 = tkinter.Entry(baseFrame)\n",
    "e2.grid(row=1, column=1, stick=tkinter.E)\n",
    "e2['show'] = '*'\n",
    "\n",
    "# Button参数command的意思是，当按钮被点击后启动相应的处理函数\n",
    "btn = tkinter.Button(baseFrame, text=\"登录\", command=reg)\n",
    "btn.grid(row=2, column=1, stick=tkinter.E)\n",
    "\n",
    "lb3 = tkinter.Label(baseFrame, text=\"\")\n",
    "lb3.grid(row = 3)\n",
    "\n",
    "# 启动主Frame\n",
    "baseFrame.mainloop()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 菜单\n",
    "### 1. 普通菜单\n",
    "- 第一个Menu类定义的是parent\n",
    "- add_command 添加菜单项，如果菜单是顶层菜单，则从左向右添加，否则就是下拉菜单\n",
    "    - label： 指定菜单项名称\n",
    "    - command: 点击后相应的调用函数\n",
    "    - acceletor： 快捷键\n",
    "    - underline： 制定是否菜单信息下有横线\n",
    "    - menu：属性制定使用哪一个作为顶级菜单\n",
    "    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# 普通菜单的代码\n",
    "import tkinter\n",
    "\n",
    "baseFrame = tkinter.Tk()\n",
    "\n",
    "menubar = tkinter.Menu(baseFrame)\n",
    "\n",
    "for item in ['File', 'Edit', 'View', 'About']:\n",
    "    menubar.add_command(label=item)\n",
    "\n",
    "baseFrame['menu'] = menubar\n",
    "\n",
    "baseFrame.mainloop()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 级联菜单\n",
    "- add_cascade:级联菜单，作用是引出后面的菜单\n",
    "- add_cascade的menu属性：指明把菜单级联到哪个菜单上\n",
    "- label： 名称\n",
    "- 过程：\n",
    "    1. 建立menu实例\n",
    "    2. add_command\n",
    "    3. add_cascade"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "import tkinter\n",
    "\n",
    "baseFrame = tkinter.Tk()\n",
    "\n",
    "menubar = tkinter.Menu(baseFrame)\n",
    "\n",
    "emenu = tkinter.Menu(menubar)\n",
    "for item in ['Copy', 'Past', 'Cut']:\n",
    "    emenu.add_command(label=item)\n",
    "\n",
    "menubar.add_cascade(label='File')\n",
    "menubar.add_cascade(label='Edit', menu=emenu)\n",
    "menubar.add_cascade(label='About')\n",
    "\n",
    "baseFrame['menu'] = menubar\n",
    "\n",
    "baseFrame.mainloop()\n",
    "   "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 弹出式菜单\n",
    "- 弹出菜单也叫上下文菜单\n",
    "- 实现的大致思路\n",
    "    1. 简理财单并向菜单添加各种功能\n",
    "    2. 监听鼠标右键\n",
    "    3. 如果右键点击，则根据位置判断弹出\n",
    "    4. 调用Menu的pop方法\n",
    "- add_separator: 添加分隔符"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [],
   "source": [
    "import tkinter\n",
    "\n",
    "def makeLabel():\n",
    "    global baseFrame\n",
    "    tkinter.Label(baseFrame, text=\"PHP是最好的编程语言，我用Python\").pack()\n",
    "\n",
    "baseFrame = tkinter.Tk()\n",
    "\n",
    "menubar = tkinter.Menu(baseFrame)\n",
    "for x in ['麻辣香菇', '气锅鸡', '东坡肘子']:\n",
    "    menubar.add_separator()\n",
    "    menubar.add_command(label=x)\n",
    "    \n",
    "menubar.add_command(label='重庆火锅', command=makeLabel)\n",
    "\n",
    "# 事件处理函数一定要至少有一个参数，且第一个参数表示的是系统事件\n",
    "def pop(event):\n",
    "    # 注意使用 event.x 和 event.x_root的区别 \n",
    "    #menubar.post(event.x_root, event.y_root)\n",
    "    menubar.post(event.x_root, event.y_root)\n",
    "\n",
    "baseFrame.bind(\"<Button-3>\", pop)\n",
    "\n",
    "baseFrame.mainloop()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### canvas 画布\n",
    "- 画布： 可以自由的在上面绘制图形的一个小舞台\n",
    "- 在画布上绘制对象， 通常用create_xxxx，xxxx=对象类型， 例如line，rectangle\n",
    "- 画布的作用是把一定组件画到画布上显示出来\n",
    "- 画布所支持的组件：\n",
    "    - arc\n",
    "    - bitmap\n",
    "    - image(BitmapImage, PhotoImage)\n",
    "    - line\n",
    "    - oval\n",
    "    - polygon\n",
    "    - rectangle\n",
    "    - text\n",
    "    - winodw（组件）\n",
    "- 每次调用create_xxx都会返回一个创建的组件的ID，同时也可以用tag属性指定其标签\n",
    "- 通过调用canvas.move实现一个一次性动作"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# 简单画布\n",
    "import tkinter\n",
    "\n",
    "baseFrame = tkinter.Tk()\n",
    "\n",
    "cvs = tkinter.Canvas(baseFrame, width=300, height=200)\n",
    "cvs.pack()\n",
    "\n",
    "# 一条线需要两个点指明起始\n",
    "# 参数数字的单位是px\n",
    "cvs.create_line(23,23, 190,234)\n",
    "cvs.create_text(56,67, text=\"I LOVE PYTHON\")\n",
    "\n",
    "\n",
    "baseFrame.mainloop()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# 画一个五角星\n",
    "import tkinter\n",
    "import math as m\n",
    "\n",
    "baseFrame = tkinter.Tk()\n",
    "\n",
    "w = tkinter.Canvas(baseFrame, width=300, height=300, background=\"gray\" )\n",
    "w.pack()\n",
    "\n",
    "\n",
    "center_x = 150\n",
    "center_y = 150\n",
    "\n",
    "r = 150\n",
    "\n",
    "# 依次存放五个点的位置\n",
    "points = [\n",
    "        #左上点\n",
    "        # pi是一个常量数字，3.1415926\n",
    "        center_x - int(r * m.sin(2 * m.pi / 5)),\n",
    "        center_y - int(r * m.cos(2 * m.pi / 5)),\n",
    "\n",
    "        #右上点\n",
    "        center_x + int(r * m.sin(2 * m.pi / 5)),\n",
    "        center_y - int(r * m.cos(2 * m.pi / 5)),\n",
    "\n",
    "        #左下点\n",
    "        center_x - int(r * m.sin( m.pi / 5)),\n",
    "        center_y + int(r * m.cos( m.pi / 5)),\n",
    "\n",
    "        #顶点\n",
    "        center_x,\n",
    "        center_y - r,\n",
    "\n",
    "        #右下点\n",
    "        center_x + int(r * m.sin(m.pi / 5)),\n",
    "        center_y + int(r * m.cos(m.pi / 5)),\n",
    "    ]\n",
    "\n",
    "# 创建一个多边形\n",
    "w.create_polygon(points, outline=\"green\", fill=\"yellow\")\n",
    "w.create_text(150,150, text=\"五角星\")\n",
    "\n",
    "baseFrame.mainloop()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "import tkinter\n",
    "\n",
    "baseFrame = tkinter.Tk()\n",
    "\n",
    "def btnClick(event):\n",
    "        global  w\n",
    "        w.move(id_ball, 12,5)\n",
    "        w.move(\"fall\", 0,5)\n",
    "\n",
    "\n",
    "\n",
    "w = tkinter.Canvas(baseFrame, width=500, height=400)\n",
    "w.pack()\n",
    "w.bind(\"<Button-1>\", btnClick)\n",
    "\n",
    "# 创建组件后返回id\n",
    "id_ball  = w.create_oval(20,20, 50,50, fill=\"green\")\n",
    "\n",
    "# 创建组件使用tag属性\n",
    "w.create_text(123,56, fill=\"red\", text=\"ILovePython\", tag=\"fall\")\n",
    "# 创建的时候如果没有指定tag可以利用addtag_withtag添加\n",
    "# 同类函数还有 addtag_all, addtag_above, addtag_xxx等等\n",
    "id_rectangle = w.create_rectangle(56,78,173,110, fill=\"gray\")\n",
    "w.addtag_withtag(\"fall\", id_rectangle)\n",
    "\n",
    "\n",
    "baseFrame.mainloop()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
